//--- Projeto Domus
// interactionsource.com
// Koji Pereira, Andre Veloso e Marcos Paulo

/*
 Projeto Domus
 interactionsource.com
 Koji Pereira, Andre Veloso e Marcos Paulo

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/


package com.interactionsource.gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;

import javax.swing.ButtonGroup;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import org.wiigee.event.AccelerationEvent;

import com.interactionsource.control.Manager;
import com.interactionsource.event.ContinuousEvent;
import com.interactionsource.event.ContinuousEventListener;
import com.interactionsource.event.TextEvent;
import com.interactionsource.event.TextEventListener;
import com.interactionsource.event.TriggerEvent;
import com.interactionsource.event.TriggerEventListener;

/**
 * This code was edited or generated using CloudGarden's Jigloo
 * SWT/Swing GUI Builder, which is free for non-commercial
 * use. If Jigloo is being used commercially (ie, by a corporation,
 * company or business for any purpose whatever) then you
 * should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details.
 * Use of Jigloo implies acceptance of these licensing terms.
 * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
 * THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
 * LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
 */
public class WiimoteOSCFrame extends JInternalFrame implements PropertyChangeListener, ActionListener, ItemListener {

	private static final long serialVersionUID = 1L;
	static int openFrameCount = 0;
	private ButtonGroup buttonGroup1;
	private JRadioButton jRadioButtonRecognition;
	private JRadioButton jRadioButtonTraining;
	private JLabel jLabelZVal;
	private JLabel jLabelYVal;
	private JLabel jLabelXVal;
	private JLabel jLabelYAxxis;
	private JLabel jLabelZAxxis;
	private JLabel jLabelXAxxis;
	private JButton jButtonTreminaTreino;
	private JScrollPane jScrollPane1;
	private JTextArea jTextAreaMessageTerminal;
	private JLabel jLabelQtLoadedGestures;
	private JLabel jLabelLoadedGestures;
	private JButton jButtonCloseGesture;
	private JLabel jLabelCheckBoxOutput;
	private JCheckBox jCheckBoxZAxis;
	private JCheckBox jCheckBoxYAxis;
	private JCheckBox jCheckBoxXAxis;
	private JLabel jLabelIncomingMessage;
	private JButton jButtonSaveGesture;
	private JLabel jLabelPortaOSC;
	private JTextField jTextFieldOSCPort;
	private JButton jButtonIniciaTreino;

	StyledDocument doc;

	static final int xOffset = 30, yOffset = 30;

	private int valorPortaOSC = 5000;

	private int idWiimoteOSC;

	private Manager manager;

	private boolean DEBUG = false;

	JFileChooser fcw;


	ValuerEventListener eventoX;
	ValuerEventListener eventoY;
	ValuerEventListener eventoZ;

	ValuerEventListener qtGestos;

	ValuerEventListener textoTerminal;

	public WiimoteOSCFrame( int idWiimoteOSC, int portaOSC, Manager manager ) {
		super("WiimoteOSC " + idWiimoteOSC, 
				false, //resizable
				false, //closable
				false, //maximizable
				true);//iconifiable

		this.valorPortaOSC = portaOSC;
		this.idWiimoteOSC = idWiimoteOSC;

		this.manager = manager;

		this.eventoX = new ValuerEventListener();
		this.eventoY = new ValuerEventListener();
		this.eventoZ = new ValuerEventListener();

		this.qtGestos = new ValuerEventListener();

		this.textoTerminal = new ValuerEventListener();

		//Create a file chooser
		fcw = new JFileChooser();

		if (DEBUG) {

		}

		initComponents() ;

		initComponentsState();
	}



	private void initComponents() {


		//Display the window.
		this.pack();
		this.setVisible(true);
		getContentPane().setLayout(null);
		this.setPreferredSize(new java.awt.Dimension(432, 350));
		this.setBounds(0, 0, 432, 350);
		{
			jButtonIniciaTreino = new JButton();
			getContentPane().add(jButtonIniciaTreino);
			jButtonIniciaTreino.setText("Start Gesture Training");
			jButtonIniciaTreino.setBounds(12, 107, 169, 21);
			jButtonIniciaTreino.setActionCommand("start");
			jButtonIniciaTreino.addActionListener(this);


		}
		{
			jButtonTreminaTreino = new JButton();
			getContentPane().add(jButtonTreminaTreino);
			jButtonTreminaTreino.setText("Finish Gesture Training");
			jButtonTreminaTreino.setBounds(12, 139, 169, 21);
			jButtonTreminaTreino.setActionCommand("finish");
			jButtonTreminaTreino.addActionListener(this);


		}
		{
			jTextFieldOSCPort = new JTextField();
			getContentPane().add(jTextFieldOSCPort);
			jTextFieldOSCPort.setText(String.valueOf(valorPortaOSC));
			jTextFieldOSCPort.setBounds(110, 9, 52, 21);
			jTextFieldOSCPort.addActionListener(this);
			jTextFieldOSCPort.setActionCommand("oscvalue");
		}
		{
			jLabelPortaOSC = new JLabel();
			getContentPane().add(jLabelPortaOSC);
			jLabelPortaOSC.setText("OSC Port");
			jLabelPortaOSC.setBounds(18, 12, 66, 14);
		}
		{
			jButtonSaveGesture = new JButton();
			getContentPane().add(jButtonSaveGesture);
			jButtonSaveGesture.setText("Save Gesture");
			jButtonSaveGesture.setBounds(231, 171, 169, 21);
			jButtonSaveGesture.setActionCommand("save");
			jButtonSaveGesture.addActionListener(this);



		}
		{
			jLabelIncomingMessage = new JLabel();
			getContentPane().add(jLabelIncomingMessage);
			jLabelIncomingMessage.setText("Incomming Signal:");
			jLabelIncomingMessage.setBounds(204, 9, 157, 14);
		}
		{
			jLabelXAxxis = new JLabel();
			getContentPane().add(jLabelXAxxis);
			jLabelXAxxis.setText("X Axis");
			jLabelXAxxis.setBounds(204, 29, 49, 14);
		}
		{
			jLabelYAxxis = new JLabel();
			getContentPane().add(jLabelYAxxis);
			jLabelYAxxis.setText("Y Axis");
			jLabelYAxxis.setBounds(265, 29, 49, 14);
		}
		{
			jLabelZAxxis = new JLabel();
			getContentPane().add(jLabelZAxxis);
			jLabelZAxxis.setText("Z Axis");
			jLabelZAxxis.setBounds(326, 29, 45, 14);
		}
		{
			jLabelXVal = new JLabel();
			getContentPane().add(jLabelXVal);
			jLabelXVal.setText("0");
			jLabelXVal.setBounds(204, 49, 49, 13);
		}
		{
			jLabelYVal = new JLabel();
			getContentPane().add(jLabelYVal);
			jLabelYVal.setText("0");
			jLabelYVal.setBounds(265, 48, 49, 14);
		}
		{
			jLabelZVal = new JLabel();
			getContentPane().add(jLabelZVal);
			jLabelZVal.setText("0");
			jLabelZVal.setBounds(326, 48, 45, 14);
		}
		{
			jRadioButtonTraining = new JRadioButton();
			getContentPane().add(jRadioButtonTraining);
			jRadioButtonTraining.setText("Training");
			jRadioButtonTraining.setBounds(18, 46, 122, 19);
			jRadioButtonTraining.setActionCommand("training");
			jRadioButtonTraining.addActionListener(this);
		}
		{
			jRadioButtonRecognition = new JRadioButton();
			getContentPane().add(jRadioButtonRecognition);
			jRadioButtonRecognition.setText("Recognition");
			jRadioButtonRecognition.setBounds(18, 74, 122, 19);
			jRadioButtonRecognition.setActionCommand("recognition");
			jRadioButtonRecognition.addActionListener(this);

		}
		{
			jButtonCloseGesture = new JButton();
			getContentPane().add(jButtonCloseGesture);
			jButtonCloseGesture.setText("Close Gesture");
			jButtonCloseGesture.setBounds(12, 171, 169, 22);
			jButtonCloseGesture.setActionCommand("closeGesture");
			jButtonCloseGesture.addActionListener(this);
		}

		buttonGroup1 = new ButtonGroup();
		buttonGroup1.add(jRadioButtonTraining);
		jRadioButtonTraining.setPreferredSize(new java.awt.Dimension(19, 122));
		buttonGroup1.add(jRadioButtonRecognition);
		jRadioButtonRecognition.setSelected(true);
		jRadioButtonRecognition.setPreferredSize(new java.awt.Dimension(19, 122));
		{
			jCheckBoxXAxis = new JCheckBox();
			getContentPane().add(jCheckBoxXAxis);
			jCheckBoxXAxis.setBounds(204, 74, 27, 17);
			jCheckBoxXAxis.addItemListener(this);
		}
		{
			jCheckBoxYAxis = new JCheckBox();
			getContentPane().add(jCheckBoxYAxis);
			jCheckBoxYAxis.setBounds(265, 74, 36, 17);
			jCheckBoxYAxis.addItemListener(this);
		}
		{
			jCheckBoxZAxis = new JCheckBox();
			getContentPane().add(jCheckBoxZAxis);
			jCheckBoxZAxis.setBounds(326, 74, 26, 17);
			jCheckBoxZAxis.addItemListener(this);
		}
		{
			jLabelCheckBoxOutput = new JLabel();
			getContentPane().add(jLabelCheckBoxOutput);
			jLabelCheckBoxOutput.setText("Enable");
			jLabelCheckBoxOutput.setBounds(359, 76, 71, 15);
		}
		{
			jLabelLoadedGestures = new JLabel();
			getContentPane().add(jLabelLoadedGestures);
			jLabelLoadedGestures.setText("Loaded Gestures:");
			jLabelLoadedGestures.setBounds(204, 109, 122, 15);
		}
		{
			jLabelQtLoadedGestures = new JLabel();
			getContentPane().add(jLabelQtLoadedGestures);
			jLabelQtLoadedGestures.setText("0");
			jLabelQtLoadedGestures.setBounds(324, 109, 36, 15);
		}
		{
			jScrollPane1 = new JScrollPane();
			getContentPane().add(jScrollPane1);
			jScrollPane1.setBounds(13, 200, 380, 100);
			jScrollPane1.setVerticalScrollBarPolicy(
					JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
			{
				jTextAreaMessageTerminal = new JTextArea();
				jScrollPane1.setViewportView(jTextAreaMessageTerminal);
				jTextAreaMessageTerminal.setText("");
				jTextAreaMessageTerminal.setEditable(false);
				jTextAreaMessageTerminal.setBounds(12, 200, 380, 100);

			}
		}

		//Registra os listenrs para modificacao dos  eventos da interface
		this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).addAccellXContinuousEventListener_2(this.eventoX);
		this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).addAccellYContinuousEventListener_2(this.eventoY);
		this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).addAccellZContinuousEventListener_2(this.eventoZ);

		this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).addQtGesturesEventListener(this.qtGestos);
		this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).addTextEventListener(this.textoTerminal);
	}

	public void initComponentsState() {

		jButtonIniciaTreino.setVisible(false);
		jButtonSaveGesture.setVisible(false);
		jButtonTreminaTreino.setVisible(false);
		jButtonCloseGesture.setVisible(false);

		jLabelQtLoadedGestures.setText(String.valueOf(this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).getQtGestos()));

	}


	public void actionPerformed(ActionEvent e) {
		if ("start".equals(e.getActionCommand())) {
			System.out.println("WiimoteOSCFrame - apertou start - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);

			this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).iniciaTreinoGesto();

		} else if ("finish".equals(e.getActionCommand())) {
			System.out.println("apertou finish - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);
			this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).terminaTreinoGesto();   

		} else if ("save".equals(e.getActionCommand())) {
			System.out.println("apertou save - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);
			int returnVal = fcw.showSaveDialog(this);

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fcw.getSelectedFile();

				try {
					System.out.println("WiimoteOSCFrame - Escolhido: " + file.getName());
					System.out.println("WiimoteOSCFrame - canonical path: " + file.getCanonicalPath() );
					System.out.println("WiimoteOSCFrame - Absolute path: " + file.getAbsolutePath() );
					System.out.println("WiimoteOSCFrame - Diretorio " + file.getParent());

					if ( this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).saveConfiguration(file.getCanonicalPath()) !=0 ) {
						//Erro no salvamento do arquivo

						//custom title, error icon
						JOptionPane.showMessageDialog(this,
								"Impossible to save gesture file \"" + file.getName() + ".txt\"",
								"Error saving gesture file",
								JOptionPane.ERROR_MESSAGE);
						return;
					} else {
						//custom title, error icon
						JOptionPane.showMessageDialog(this,
								"Gesture \"" + file.getName() + ".txt\" successfully saved",
								"Saving gesture file...",
								JOptionPane.PLAIN_MESSAGE);
						return;

					} 

				}  catch (IOException e1) {

					e1.printStackTrace();
					return;
				}
			}


		} else if ("closeGesture".equals(e.getActionCommand())) {
			System.out.println("apertou closeGesture - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);
			this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).salvaGesto();   

		} else if ("oscvalue".equals(e.getActionCommand())) {
			System.out.println("apertou oscvalue - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);

			this.valorPortaOSC = Integer.parseInt(jTextFieldOSCPort.getText());

			this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setOscPort( this.valorPortaOSC );

		} else if ("training".equals(e.getActionCommand())) {
			System.out.println("apertou training - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);

			//Os botoes de salvamento soh aparecem no modo de traning
			jButtonIniciaTreino.setVisible(true);
			jButtonSaveGesture.setVisible(true);
			jButtonTreminaTreino.setVisible(true);
			jButtonCloseGesture.setVisible(true);

			this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setReconhecendoGestoEnabled(false);


		} else if ("recognition".equals(e.getActionCommand())) {
			System.out.println("apertou recognition - id: " + 
					idWiimoteOSC + " porta: " + valorPortaOSC);


			jButtonIniciaTreino.setVisible(false);
			jButtonSaveGesture.setVisible(false);
			jButtonTreminaTreino.setVisible(false);
			jButtonCloseGesture.setVisible(false);

			this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setReconhecendoGestoEnabled(true);

		}
	}

	public void itemStateChanged(ItemEvent e) {

		Object source = e.getItemSelectable();

		System.out.println("WiimoteOSCFrame - apertou jCheckBox - id: " + 
				idWiimoteOSC + " porta: " + valorPortaOSC + " State: " + e.getStateChange());

		if (source == jCheckBoxXAxis) {

			if (e.getStateChange() == ItemEvent.DESELECTED) {
				this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setAccellXEnabled(false);

			} else {
				this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setAccellXEnabled(true);

			}

		} else if (source == jCheckBoxYAxis) {

			if (e.getStateChange() == ItemEvent.DESELECTED) {
				this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setAccellYEnabled(false);

			} else {
				this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setAccellYEnabled(true);

			}

		} else if (source == jCheckBoxZAxis) {

			if (e.getStateChange() == ItemEvent.DESELECTED) {
				this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setAccellZEnabled(false);

			} else {
				this.manager.getWiimoteOSCDeviceAt(idWiimoteOSC-1).setAccellZEnabled(true);

			}
		}

	}


	/** Called when a field's "value" property changes. */
	public void propertyChange(PropertyChangeEvent e) {

		/*
    	Object source = e.getSource();
        if (source == portaOSC) {

        } 
		 */		 
	}

	/**
	 * @return the valorPortaOSC
	 */
	public int getValorPortaOSC() {
		return valorPortaOSC;
	}



	/**
	 * @param valorPortaOSC the valorPortaOSC to set
	 */
	public void setValorPortaOSC(int valorPortaOSC) {
		this.valorPortaOSC = valorPortaOSC;
	}



	/**
	 * @return the idWiimoteOSC
	 */
	public int getIdWiimoteOSC() {
		return idWiimoteOSC;
	}



	/**
	 * @param idWiimoteOSC the idWiimoteOSC to set
	 */
	public void setIdWiimoteOSC(int idWiimoteOSC) {
		this.idWiimoteOSC = idWiimoteOSC;
	}



	public void addStartGestureTrainingButtonListener(ActionListener sgtl) {
		jButtonIniciaTreino.addActionListener(sgtl);
	}

	public void addFinishGestureTrainingButtonListener(ActionListener fgtl) {
		jButtonTreminaTreino.addActionListener(fgtl);
	}

	public void addSaveGestureButtonListener(ActionListener sg) {
		jButtonSaveGesture.addActionListener(sg);
	}


	class ValuerEventListener implements TriggerEventListener, ContinuousEventListener, TextEventListener {


		public void triggerEventReceived(TriggerEvent event) {


			jLabelQtLoadedGestures.setText(String.valueOf((int)event.getValue()));

		}

		public void continuousEventReceived(ContinuousEvent event) {


			AccelerationEvent ev = (AccelerationEvent)event.getSource();

			jLabelXVal.setText( String.valueOf(ev.getX()) );
			jLabelYVal.setText( String.valueOf(ev.getY()) );
			jLabelZVal.setText( String.valueOf(ev.getZ()) );

		}


		public void textEventReceived(TextEvent event) {
			// TODO Auto-generated method stub


			jTextAreaMessageTerminal.append(event.getText() + "\n");
			jTextAreaMessageTerminal.setCaretPosition(jTextAreaMessageTerminal.getDocument().getLength());



		}

	}


}
